package com.ruoyi.by.health.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.ruoyi.by.health.domain.entity.ByhealthEmployee;
import com.ruoyi.by.health.domain.entity.ByhealthLotteryOutcome;
import com.ruoyi.by.health.domain.form.EmployeeGameForm;
import com.ruoyi.by.health.domain.form.WechatRegisteredForm;
import com.ruoyi.by.health.domain.vo.EmployeeGameVo;
import com.ruoyi.by.health.mapper.ByhealthEmployeeMapper;
import com.ruoyi.by.health.service.IByhealthEmployeeService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Validator;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

/**
 * 用户 业务层处理
 *
 * @author ruoyi
 */
@Service
public class ByhealthEmployeeServiceImpl implements IByhealthEmployeeService {
    private static final Logger log = LoggerFactory.getLogger(ByhealthEmployeeServiceImpl.class);
    @Autowired
    protected Validator validator;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ByhealthEmployeeMapper employeeMapper;
    @Autowired
    private WxMpService wxMpService;
    @Autowired
    private WxMaService wxMaService;


    @Override
    public List<ByhealthEmployee> selectEmployeeList(ByhealthEmployee emp) {
        return employeeMapper.selectEmployeeList(emp);
    }

    @Override
    public List<ByhealthEmployee> selectEmployeeListNoLottery(ByhealthLotteryOutcome lotteryOutcome) {
        return employeeMapper.selectEmployeeListNoLottery(lotteryOutcome);
    }

    @Override
    public List<ByhealthEmployee> selectRandomEmployeeList(Integer count) {
        return employeeMapper.selectRandomEmployeeList(count);
    }

    @Override
    public ByhealthEmployee selectEmployeeByCode(String empCode) {
        return employeeMapper.selectEmployeeByCode(empCode);
    }

    @Override
    public ByhealthEmployee selectEmployeeByEmpId(Long empId) {
        return employeeMapper.selectEmployeeByEmpId(empId);
    }

    @Override
    public ByhealthEmployee selectEmployeeByOpenId(String openId) {
        return employeeMapper.selectEmployeeByOpenId(openId);
    }

    @Override
    public ByhealthEmployee selectEmployeeByAppOpenId(String appOpenId) {
        return employeeMapper.selectEmployeeByAppOpenId(appOpenId);
    }

    @Override
    public AjaxResult gameScore(EmployeeGameForm gameForm) {
        Long empId = gameForm.getEmpId();
        Long gameScore = gameForm.getGameScore();
        log.info("scoreId:{},gameScore:{}", empId, gameForm.gameScore);
        ByhealthEmployee employee = employeeMapper.selectEmployeeByEmpId(empId);
        if (employee == null) {
            return AjaxResult.error("员工信息不存在");
        }
        log.info("----现在的游戏得分数是gameScore:{}", gameScore);
        ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();
        Double score = zSetOperations.score("emp_game_score", empId);
        Long gameRank = 0L;
        EmployeeGameVo employeeGameVo = new EmployeeGameVo();
        if (Objects.isNull(score)) {
            log.info("----第一次提交份数");
            zSetOperations.add("emp_game_score", empId, gameScore);
            gameRank = zSetOperations.reverseRank("emp_game_score", empId) + 1;
            employeeGameVo.setGameScore(gameScore);
            employeeGameVo.setGameRank(gameRank);
            employeeMapper.updateEmployeeGame(empId, gameScore, gameRank);
        } else {
            log.info("----获取到的原来分份数是gameScore:{}", score);
            BigDecimal scoreDecimal = new BigDecimal(score);
            BigDecimal gameScoreDecimal = new BigDecimal(gameScore);
            log.info("----两次的游戏的得分比较:{}", scoreDecimal.compareTo(gameScoreDecimal));
            if (scoreDecimal.compareTo(gameScoreDecimal) >= 0) {
                gameRank = zSetOperations.reverseRank("emp_game_score", empId) + 1;
                employeeGameVo.setGameScore(score.longValue());
            } else {
                zSetOperations.add("emp_game_score", empId, gameScore);
                gameRank = zSetOperations.reverseRank("emp_game_score", empId) + 1;
                employeeGameVo.setGameScore(gameScore);
                employeeGameVo.setGameRank(gameRank);
                employeeMapper.updateEmployeeGame(empId, gameScore, gameRank);
            }
        }
        BeanUtils.copyBeanProp(employee, employeeGameVo);
        employee.setGameRank(gameRank);
        return AjaxResult.success(employee);
    }


    @Override
    public List<EmployeeGameVo> gameScoreList(EmployeeGameForm gameForm) {
        List<EmployeeGameVo> result = employeeMapper.gameScoreList(gameForm);
        //log.info("----------result:{}", JSON.toJSONString(result));
        return result;
    }

    @Override
    public AjaxResult registerEmployee(WechatRegisteredForm emp) {
        if (!StringUtils.isEmpty(emp.getCode()) || !StringUtils.isEmpty(emp.getMiniCode())) {
            ByhealthEmployee employee = employeeMapper.selectByCodeAndPhone(emp.getEmpCode(), emp.getPhone());
            if (!Objects.isNull(employee)) {
                String openId = null;
                String appOpenId = null;
                if (!employee.getPhoneNumber().equals(emp.getPhone())) {
                    return AjaxResult.error("员工手机号信息不符合");
                }
                if (!employee.getEmpName().equals(emp.getEmpName())) {
                    return AjaxResult.error("员工姓名信息不符合");
                }
                // 微信公众号
                try {
                    if (!StringUtils.isEmpty(emp.getCode())) {
                        WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(emp.getCode());
                        openId = accessToken.getOpenId();
                    }

                    if (!StringUtils.isEmpty(emp.getMiniCode())) {
                        WxMaJscode2SessionResult wxSession = wxMaService.getUserService().getSessionInfo(emp.getMiniCode());
                        appOpenId = wxSession.getOpenid();
                        ByhealthEmployee employeeApp = employeeMapper.selectEmployeeByAppOpenId(appOpenId);
                        if (Objects.nonNull(employeeApp)) {
                            return AjaxResult.error("该微信已绑定");
                        }
                            /*WxMaUserInfo userInfo = wxMaService.getUserService()
                                    .getUserInfo(wxSession.getSessionKey(),)*/
                    }
                    employeeMapper.updateEmployeeOpenId(employee.getEmpId(), openId, appOpenId);
                } catch (WxErrorException e) {
                    e.printStackTrace();
                }
            } else {
                return AjaxResult.error("员工信息不存在");
            }
            return AjaxResult.success(employee);
        } else {
            return AjaxResult.error("公众号或者小程序code 不能同时为空");
        }

    }

    @Override
    public int insertEmployee(ByhealthEmployee emp) {
        return employeeMapper.insertEmployee(emp);
    }

    @Override
    public int updateEmployee(ByhealthEmployee emp) {
        return employeeMapper.updateEmployee(emp);
    }

    @Override
    public String importEmployee(List<ByhealthEmployee> empList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(empList) || empList.size() == 0) {
            throw new ServiceException("导入用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (ByhealthEmployee employee : empList) {
            try {
                // 验证是否存在这个用户
                ByhealthEmployee u = employeeMapper.selectEmployeeByCode(employee.getEmpCode());
                if (StringUtils.isNull(u)) {
                    BeanValidators.validateWithException(validator, employee);
                    employee.setCreateBy(operName);
                    this.insertEmployee(employee);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + employee.getEmpCode() + " 导入成功");
                } else if (isUpdateSupport) {
                    BeanValidators.validateWithException(validator, employee);
                    employee.setUpdateBy(operName);
                    this.updateEmployee(employee);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + employee.getEmpCode() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、账号 " + employee.getEmpCode() + " 已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + employee.getEmpCode() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    public Integer allEmployeeCount() {
        return employeeMapper.allEmployeeCount();
    }

    @Override
    public Integer allBossCount() {
        return employeeMapper.allBossCount();
    }
}
